/***************************************************************************
 *   Copyright (C) 2004 by Paul Lutus                                      *
 *   lutusp@arachnoid.com                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

static const char *HelpText = "*** Help for FFTExplorer\n\nFFTExplorer is (c) Copyright 2004, P. Lutus.\n\nFFTExplorer is released under the GPL (the GNU General Public License). Additionally, it is CareWare (no money, now or ever). Visit the CareWare Page at www.arachnoid.com/careware.\n\nFor recent revisions and further information, visit the FFTExplorer Home Page at http://www.arachnoid.com/FFTExplorer.\n\n*** Introduction\n\nFFTExplorer is a Linux-specific C++ program meant to provide a spectrum analysis tool in an easy-to use form. It relies on a mathematical method known as a \"Fast Fourier Transform.\" The Fast Fourier Transform (hereafter FFT) converts a time-varying signal into a frequency-domain dataset, so that a typical time-varying signal is converted into a set of spectral lines that describe the original signal in terms of its frequency components.\n\nThe operation of FFTExplorer can be described in these steps:\n\n1. Collect time-varying data, from a sound card's digital signal processor, or a sound file, or a named pipe whose purpose it is to provide an interface to any arbitrary source of program data (more on this later).\n\n2. Using the FFT method, convert the time-varying data into a frequency spectrum.\n\n3. Display the result.\n\nEach of these steps has several variations and options. One can choose the number of samples per second, information that is passed along to a sound card if that is the data source, and one can choose the size of the FFT array, which increases the resolution of the result as the array becomes larger (in exchange for more processing time).\n\n*** Sound card data source\n\nWhen one uses a sound card as a data source, for example while using a microphone, one may wish to maximize the speed of the display. To do this, it is best to choose a relatively small FFT array size and a relatively high sampling rate, because this specific kind of data acquisition takes place in real time. The defaults are a sampling rate of 44100 samples per second, the quality level for music CDs, and an FFT array size of 8192 data points. It is important to realize about these choices that we are trading resolution for update speed. If update speed were not an issue, we would choose an FFT array size roughly equal to the sampling rate, but this would obviously mean a display update time of something greater than one second.\n\nThe user should experiment with the sample rate and the FFT array size to get a satisfactory compromise between update speed and spectrum resolution. Remember that the FFT array size must be a power of 2, e.g. 2048, 8192, 16384, etc.. These values are automatically created by FFTExplorer based on the number you enter (so it is not necessary to memorize a lot of powers of 2).\n\nSound card levels are typically low, so if you don't see the microphone output as expected, be sure to experiment with raising the display vertical amplitude setting to, say, 100.\n\nIt is also important to point out that many modern PC sound cards can acquire data at a higher sampling rate than the music-CD standard of 44,100 samples per second. I find most current sound cards can operate at 192,000 samples per second. If you enter a very large number for samples per second, the program will inquire with the sound card and reply with the highest acceptable speed.\n\nI usually set the samples per second figure at the highest practical rate of 192,000 and choose an FFT array size of 8192 data points. On the fastest PCs the display update rate is somewhat slower than the FFT array size divided by the sampling rate, or, in this example:\n\n8192 / 192000 = 42.6 milliseconds\n\nThis estimate doesn't take into account the time required to convert and display the sample. In this case it is likely the total time required is about 100 milliseconds, or ten conversions and displays per second. One may wish to accept a slower conversion rate in exchange for greater spectral resolution. For this scenario, choose a larger FFT array size.\n\n*** Other data sources\n\nFFTExplorer can use its own internal signal source, useful for experimentation and technique development, various sound file types, or a named pipe as an easy interface to various software data sources.\n\nHere is an example using the internal signal source. Go to the configuration tab and choose Source ... Internal. Make the following settings:\n\nSampling rate:        32768 samples per second\nFFT array size:       32768 data points\nCarrier frequency:    1000 Hz\nModulation Frequency: 100 Hz\nModulation Level:     100 %\nNoise level:          100 %\n\nRemember after making these settings to click the \"Accept\" button if it is is enabled, to allow your changes to take effect.\n\nThen press the \"Start\" button at the lower left of the program window, click the tab marked \"both\", and make these settings in the display window that will appear:\n\nTime display (top):\n\nTime Span: 20 ms\nAmplitude: 0.5\n\nFrequency dispay (bottom):\n\nFrequency Span: 1.6384 KHz\nAmplitude:      1\n\nThese settings will provide a reasonable-looking time-varying waveform in the top display and a frequency specrum consisting of three lines in the bottom display, plus some noise in both displays, added just to imitate reality.\n\nUnless your computer is very slow, you will notice the update rate is higher now than it was for the sound card example, because, even though the sampling rate is 32768 samples per second, the program is most likely sampling and displaying at much better than real-time. To put it another way, the program is not tied to a real-time clock, and is therefore free to generate and display the data as fast as it can.\n\nExperiment with the display controls. Try raising the noise level to see what effect this has. Then, while using a noise level of 5000 % (yes!), select the \"Averaging\" feature of the lower (frequency) display. This is a moving-average feature that rejects random noise very effectively, while reinforcing the desired signal. If you have plenty of RAM, you may want to increase the \"Moving Average Period\" to 64 or 128 to see how this improves the noise rejection.\n\nAt this point I ask that you stop and think about what is happening. We have created a rather typical case of a signal thoroughly buried in noise (as you can see from the top display), then we apply two methods: a Fast Fourier Transform to convert the time-varying waveform into a frequency spectrum, then we apply a moving average to greatly reduce the noise and allow the signal to reappear.\n\nThis is the essence of spectrum analysis, and it is why these methods are so effective and popular in analyzing and cleaning up noisy signals. It is why this method is the primary search technique used by the SETI (Search for ExtraTerrestrial Intelligence) project, a project that listens for alien broadcasts. There may well be no one out there sending any signals for us to hear, but in carrying out this example one can see that the right tools are being applied.\n\nAlso, the signal created in this example by the internal source is more or less that of an AM radio transmitter with a carrier frequency and two sidebands. The resulting spectrum is a simplified version of what one would see if one analyzed the spectrum of a normal AM radio transmitter.\n\n*** Named Pipe as source\n\nWhile designing this program, I wanted to allow any data source to provide input to the spectrum analyzer. I realized a named pipe would provide an easy interface.\n\nA \"named pipe\" is a feature of Linux and other Unices that allows one program to send data to a specified \"file\" that is in fact a pipe (or, if you will, a stream) and another program to read the data flowing though the pipe. Here is a step-by-step procedure:\n\n1. Open a command shell and create the pipe:\n\n$ mkfifo /tmp/FFTPipe\n\nThe name and location is not important, but it should be placed somewhere convenient. This command creates the named pipe.\n\n2. Run FFTExplorer, choose the configuration tab, choose Source ... External, type in the path to the named pipe: \"/tmp/FFTPipe\". Using the \"format\" drop-down list, select a format of \"Plain Text Floating-Point Values\".\n\n3. Choose a sample rate of 32768 and an FFT array size also of 32768.\n\n4. Press the \"Start\" button, click the \"both\" display tab and you will see a message saying \"No data from source /tmp/FFTPipe\". This means all is well, and FFTExplorer is waiting for data.\n\n5. At this point, you can use any program that comes to hand that can create a signal with a specified number of samples per second. If you have some file handling skills and are willing to experiment, use the C++ program below:\n\n******************************************************\n\n#include <cstdio>\n#include <cmath>\n\nint main(int argc, char **argv)\n{\n   FILE *fp = fopen(\"/tmp/FFTPipe\",\"w\");\n   double durationSeconds = 100000;\n   double samplesPerSecond = 32768;\n   double f = 1000.0;\n   double step = 1.0/samplesPerSecond;\n   for(double t = 0;t < durationSeconds;t += step)\n   {\n      double v = sin(2 * M_PI * f * t);\n      fprintf(fp,\"%lf\\n\",v);\n   }\n   fclose(fp);\n   return 0;\n}\n\n******************************************************\n\nPut the above content in a file named \"simple_source.cpp\", put the file in any convenient location, and enter these commands to a command shell:\n\n$ make simple_source\n$ ./simple_source\n\nThe first command will build the program, the second will run it. If you have FFTExplorer running with the settings specified earlier, it will show a single spectral line at 1000 Hz.\n\nRemember about examples like this, unlike the earlier sound-card example, that they typically run much faster than real-time.\n\nNotice about the example program above that the simplest format accepted by FFTExplorer is a plain-text stream of floating-point values, each delimited by a linefeed. There are other acceptable data formats, but this is the easiest to write into a generator or data converter program.\n\nHere are some rules for external-source data acquisition:\n\n1. Make sure the samples per second selection in FFTExplorer and your source are in agreement.\n\n2. In most cases (except while using a sound card), using a power of 2 for the FFT array size and the samples per second is the best arrangement, and these entered values should in most cases be the same number.\n\nUsing a power of 2 as the samples-per-second value also helps synchronize the source with the spectrum analyzer, an important factor when using the signal averaging feature to extract weak signals from noisy sources (more on this below).\n\n*** Signal averaging\n\nFFTExplorer uses a moving-average method to help reduce noise levels from real-world signal sources. Selecting a larger value for \"Moving Average Period\" improves the performance of this feature, but at the cost of greater memory usage. The amount of memory required for this feature is:\n\nFFT array size * Moving Average Period * 8 (size of double) * 2 (number of required arrays) bytes.\n\nSo, using a Moving Average Period of 64 and an FFT Array size of 8192, one needs 8.4 megabytes of RAM for each display that uses the averaging feature. This feature obviously is meant to be used on systems with plenty of RAM.\n\nThere are some technical aspects to the moving average feature that deserve mention. The averaging is carried out separately on the real and imaginary FFT components because this produces the best results, but this means the signal source must be in phase synchrony with the analyzer for best performance. This is one reason to use the specific FFT array size and sample per second values described above.\n\nOne final note about the moving average. You will notice that the random noise that is added to the internal signal source is never entirely eliminated by the moving average feature, even when one chooses a very large value for the Moving Average Period. After a substantial amount of analysis of this effect, I have concluded that it is caused by periodicity in the standard C++ pseudo-random number generator. I am reasonably sure that a truly random noise source would not show this irreducible pattern, although I don't have such a source to experiment with.\n\n*** Integration with SignalGen\n\nI have a signal generator program available for download on my site, at http://www.arachnoid.com/SignalGen. You may use this signal source with FFTExplorer by using the above-described named pipe method, but be sure the two programs use the same samples per second rate, and select a \"Format\" of 16-bit Signed in FFTExplorer's configuration window.\n\n*** User support\n\nBecause FFTExplorer is free/GPL (but please visit http://www.arachnoid.com/careware anyway), there is no user support. The program is very easy to use, this help file and various flyout text messages are integrated into it, and common sense should be able to stand in for user support.\n\nIf you detect a bug in FFTExplorer, please report it at http://www.arachnoid.com/messages. Make sure what you are reporting is in fact a bug. :)\n\n-- P. Lutus, Port Hadlock, WA";
